
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using System.Collections;
using System.Xml;
using System.Configuration;
using System.Diagnostics;

namespace Pub
{
    public class CTextEditMenu
    {

        public TextEditorControl textBox;

        public ContextMenuStrip richMenu;


        public ToolStripMenuItem CM_cut;
        public ToolStripMenuItem CM_copy;
        public ToolStripMenuItem CM_paste;
        public ToolStripMenuItem CM_selectAll;
        public ToolStripMenuItem CM_del;
        public ToolStripMenuItem CM_cancle;
        public ToolStripMenuItem CM_align;

        public ToolStripMenuItem CM_find;
        public ToolStripMenuItem CM_replace;
        public ToolStripMenuItem CM_findNext;
        public ToolStripMenuItem CM_findPrve;

        public ToolStripMenuItem CM_bookmark;
        public ToolStripMenuItem CM_bookmarkNext;
        public ToolStripMenuItem CM_bookmarkPrve;

        public ToolStripMenuItem CM_setting;
        public ToolStripMenuItem CM_splitWindow;
        public ToolStripMenuItem CM_showSpaceTab;
        public ToolStripMenuItem CM_showEOLMarker;
        public ToolStripMenuItem CM_showInvalidLine;
        public ToolStripMenuItem CM_showLineNumbers;
        public ToolStripMenuItem CM_showHighlightLine;
        public ToolStripMenuItem CM_showVirtualSapce;

        public ToolStripMenuItem CM_tabToSpace;
        public ToolStripMenuItem CM_tabSize;
        public ToolStripMenuItem CM_setFont;

        public ToolStripMenuItem CM_language;

        public ToolStripMenuItem[] CM_lg_array;
        public string[] sItemLanguage = new string[]{  
            "ASP/XHTML"    ,
            "BAT"          ,
            "Boo"          ,
            "Coco"         ,
            "C++.NET"      ,
            "C#"           ,
            "HTML"         ,
            "Java"         ,
            "JavaScript"   ,
            "Patch"        ,
            "PHP"          ,
            "TeX"          ,
            "VBNET"        ,
            "XML"          ,
            "TSQL"         ,
            "Python"       };


        public CTextEditMenu()
        {
            init();
        }

        public CTextEditMenu(TextEditorControl textBox)
        {
            this.textBox = textBox;

            init();

            this.textBox.ContextMenuStrip = richMenu;

            CM_align.Visible = false;

            //绑定事件
            //textBox.ActiveTextAreaControl.TextArea.KeyDown += new System.Windows.Forms.KeyEventHandler(keyDown_event);
            

        }


        //void keyDown_event(object sender, KeyEventArgs e)
        //{
        //    ICSharpCode.TextEditor.TextEditorControl m = sender as ICSharpCode.TextEditor.TextEditorControl;
        //    //按下ctrl+X 剪切
        //    if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.X)
        //    {
        //        CM_cut.PerformClick();
        //    }
        //    //按下ctrl+C 复制
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.C)
        //    {
        //        CM_copy.PerformClick();
        //    }
        //    //按下ctrl+V 粘贴
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.V)
        //    {
        //        CM_paste.PerformClick();
        //    }
        //    //按下ctrl+A 查找
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.A)
        //    {
        //        CM_selectAll.PerformClick();
        //    }
        //    //按下ctrl+D 删除
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.D)
        //    {
        //        CM_del.PerformClick();
        //    }
        //    //按下ctrl+U 撤销
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.U)
        //    {
        //        CM_cancle.PerformClick();
        //    }
        //    //按下ctrl+F 查找
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.F)
        //    {
        //        CM_find.PerformClick();
        //    }
        //    //按下ctrl+H 替换
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.H)
        //    {
        //        CM_replace.PerformClick();
        //    }
        //    //按下ctrl+N 下一个
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.N)
        //    {
        //        CM_findNext.PerformClick();
        //    }
        //    //按下ctrl+P 上一个
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.P)
        //    {
        //        CM_findPrve.PerformClick();
        //    }
        //    //按下ctrl+B 设置/取消书签
        //    else if (e.Modifiers.CompareTo(Keys.Control) == 0 && e.KeyCode == Keys.B)
        //    {
        //        CM_bookmark.PerformClick();
        //    }
        //}


        public void init()
        {
            richMenu = new ContextMenuStrip();

            CM_cut = new ToolStripMenuItem("剪切(&X)", null, new EventHandler(CMcut_Click));
            CM_copy = new ToolStripMenuItem("复制(&C)", null, new EventHandler(CMcopy_Click));
            CM_paste = new ToolStripMenuItem("粘贴(&V)", null, new EventHandler(CMpaste_Click));
            CM_selectAll = new ToolStripMenuItem("全选(&A)", null, new EventHandler(CMselectall_Click));
            CM_del = new ToolStripMenuItem("删除(&D)", null, new EventHandler(CMdel_Click));
            CM_cancle = new ToolStripMenuItem("撤销(&U)", null, new EventHandler(CMcancle_Click));
            CM_align = new ToolStripMenuItem("右对齐", null, new EventHandler(CMalign_Click));

            CM_find = new ToolStripMenuItem("查找(&F)", null, new EventHandler(miEditFind_Click));
            CM_replace = new ToolStripMenuItem("替换(&H)", null, new EventHandler(miEditReplace_Click));
            CM_findNext = new ToolStripMenuItem("查找下一个(&N)", null, new EventHandler(miEditFindNext_Click));
            CM_findPrve = new ToolStripMenuItem("查找上一个(&P)", null, new EventHandler(miEditFindPrev_Click));

            CM_bookmark = new ToolStripMenuItem("设置/取消书签(&B)", null, new EventHandler(miToggleBookmark_Click));
            CM_bookmarkNext = new ToolStripMenuItem("转到下一书签", null, new EventHandler(miGoToNextBookmark_Click));
            CM_bookmarkPrve = new ToolStripMenuItem("转到上一书签", null, new EventHandler(miGoToPrevBookmark_Click));

            CM_setting = new ToolStripMenuItem("设置");
            CM_splitWindow = new ToolStripMenuItem("拆分窗口(&W)", null, new EventHandler(ItemSetting_Click));
            CM_showSpaceTab = new ToolStripMenuItem("显示空格和制表符(&S)", null, new EventHandler(ItemSetting_Click));
            CM_showEOLMarker = new ToolStripMenuItem("显示换行标记(&E)", null, new EventHandler(ItemSetting_Click));
            CM_showInvalidLine = new ToolStripMenuItem("显示无效行标记(&I)", null, new EventHandler(ItemSetting_Click));
            CM_showLineNumbers = new ToolStripMenuItem("显示行号(&L)", null, new EventHandler(ItemSetting_Click));
            CM_showHighlightLine = new ToolStripMenuItem("高亮当前行(&R)", null, new EventHandler(ItemSetting_Click));
            CM_showVirtualSapce = new ToolStripMenuItem("启用须空格(&P)", null, new EventHandler(ItemSetting_Click));

            CM_tabToSpace = new ToolStripMenuItem("制表符转为空格", null, new EventHandler(ItemSetting_Click));
            CM_tabSize = new ToolStripMenuItem("设置制表符大小(&T)", null, new EventHandler(ItemSetting_Click));
            CM_setFont = new ToolStripMenuItem("字体(&F)", null, new EventHandler(ItemSetting_Click));

            CM_language = new ToolStripMenuItem("语言(&L)");

            //绑定快捷键
            CM_cut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X)));
            CM_copy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
            CM_paste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
            CM_selectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
            CM_del.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D)));
            CM_cancle.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));
            CM_find.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
            CM_replace.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));
            CM_findNext.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
            CM_findPrve.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P)));
            
            richMenu.Items.Add(CM_cut);
            richMenu.Items.Add(CM_copy);
            richMenu.Items.Add(CM_paste);
            richMenu.Items.Add(CM_selectAll);
            richMenu.Items.Add("-");
            richMenu.Items.Add(CM_del);
            richMenu.Items.Add(CM_cancle);
            richMenu.Items.Add("-");
            richMenu.Items.Add(CM_align);
            richMenu.Items.Add(CM_find);
            richMenu.Items.Add(CM_replace);
            richMenu.Items.Add(CM_findNext);
            richMenu.Items.Add(CM_findPrve);
            richMenu.Items.Add("-");
            richMenu.Items.Add(CM_bookmark);
            richMenu.Items.Add(CM_bookmarkNext);
            richMenu.Items.Add(CM_bookmarkPrve);
            richMenu.Items.Add("-");
            richMenu.Items.Add(CM_language);
            richMenu.Items.Add(CM_setting);

            CM_setting.DropDownItems.Add(CM_splitWindow);
            CM_setting.DropDownItems.Add(CM_showSpaceTab);
            CM_setting.DropDownItems.Add(CM_showEOLMarker);
            CM_setting.DropDownItems.Add(CM_showInvalidLine);
            CM_setting.DropDownItems.Add(CM_showLineNumbers);
            CM_setting.DropDownItems.Add(CM_showHighlightLine);
            CM_setting.DropDownItems.Add(CM_showVirtualSapce);
            CM_setting.DropDownItems.Add("-");
            CM_setting.DropDownItems.Add(CM_tabToSpace);
            CM_setting.DropDownItems.Add(CM_tabSize);
            CM_setting.DropDownItems.Add(CM_setFont);


            CM_lg_array = new ToolStripMenuItem[sItemLanguage.Length];

            for (int i = 0; i < sItemLanguage.Length; i++)
            {
                CM_lg_array[i] = new ToolStripMenuItem(sItemLanguage[i]);
                CM_lg_array[i].Tag = 100 + i;
                CM_lg_array[i].Click += ItemLanguage_Click;
                CM_language.DropDownItems.Add(CM_lg_array[i]);
            }



            richMenu.Opened += contextMenuStrip1_Opened;
        }

        /// <summary>
        /// 返回选中的文本
        /// </summary>
        public string SelectedText
        {
            get
            {
                return textBox.ActiveTextAreaControl.TextArea.SelectionManager.SelectedText;
            }
        }

        /// <summary>
        /// 追加内容
        /// </summary>
        /// <param name="sText"></param>
        public void AppendText(string sText)
        {
            this.textBox.Text += sText;
        }

        public void ItemLanguage_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;

            int i_btn = (int)(item.Tag);
            string sName = item.Text;

            textBox.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy(sName);
            textBox.Encoding = System.Text.Encoding.Default;
        }

        public void ItemSetting_Click(object sender, EventArgs e)
        {
            ((ToolStripMenuItem)sender).Checked = !((ToolStripMenuItem)sender).Checked;
            /*
            //this.CM_splitWindow.Checked = textBox.IsSplited;
            this.CM_showSpaceTab.Checked = _editorSettings.ShowSpaces;
            this.CM_showEOLMarker.Checked = _editorSettings.ShowEOLMarker;
            this.CM_showInvalidLine.Checked = _editorSettings.ShowInvalidLines;
            this.CM_showHighlightLine.Checked = _editorSettings.LineViewerStyle == LineViewerStyle.FullRow;
            //this.CM_showHLCurRow.Checked = _editorSettings.BracketMatchingStyle == BracketMatchingStyle.After;
            this.CM_showVirtualSapce.Checked = _editorSettings.AllowCaretBeyondEOL;
            this.CM_showLineNumbers.Checked = _editorSettings.ShowLineNumbers;

            this.CM_tabToSpace.Checked = textBox.ConvertTabsToSpaces;
            */

            OnSettingsChanged();
        }

        #region 编辑选项

        /// <summary>
        /// 右键菜单 阅读顺序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMalign_Click(object sender, EventArgs e)
        {
            CM_align.Checked = !CM_align.Checked;
            if (CM_align.Checked == true)
            {
                textBox.ActiveTextAreaControl.TextArea.RightToLeft = RightToLeft.Yes;
            }
            else
            {
                textBox.ActiveTextAreaControl.TextArea.RightToLeft = RightToLeft.No;
            }
        }

        /// <summary>
        /// 右键菜单 撤销
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMcancle_Click(object sender, EventArgs e)
        {
            if (CM_cancle.Enabled == true)
            {
                textBox.Undo();
                //richTextBox.ClearUndo();
            }
        }

        /// <summary>
        /// 右键菜单 复制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMcopy_Click(object sender, EventArgs e)
        {
            if (CM_copy.Enabled == true)
            {
                miEditCopy_Click(sender, e);
            }
        }

        /// <summary>
        /// 右键菜单剪切
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMcut_Click(object sender, EventArgs e)
        {
            if (CM_cut.Enabled == true)
            {
                miEditCut_Click(sender, e);
            }
        }

        /// <summary>
        /// 右键菜单 删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMdel_Click(object sender, EventArgs e)
        {
            if (CM_del.Enabled == true)
            {
                miEditDelete_Click(sender, e);
            }
        }

        /// <summary>
        /// 右键菜单 粘贴
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMpaste_Click(object sender, EventArgs e)
        {
            if (CM_paste.Enabled == true)
            {
                miEditPaste_Click(sender, e);
            }
        }

        /// <summary>
        /// 右键菜单 全选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CMselectall_Click(object sender, EventArgs e)
        {
            miEditSelectAll_Click(sender, e);
        }

        /// <summary>
        /// 右键菜单 按钮可见
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextMenuStrip1_Opened(object sender, EventArgs e)
        {
            if (SelectedText.Length > 0)
            {
                CM_copy.Enabled = true;
                CM_cut.Enabled = true;
                CM_del.Enabled = true;
            }
            else
            {
                CM_copy.Enabled = false;
                CM_cut.Enabled = false;
                CM_del.Enabled = false;
            }

            if (textBox.EnableUndo == true)
            {
                this.CM_cancle.Enabled = true;
            }
            else
            {
                this.CM_cancle.Enabled = false;
            }

            if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Text))
            {
                this.CM_paste.Enabled = true;
            }
            else
            {
                this.CM_paste.Enabled = false;
            }

            if (textBox.Text != "")
            {
                CM_selectAll.Enabled = true;
            }
            else
            {
                CM_selectAll.Enabled = false;
            }
        }

        #endregion

        #region xml相关
        /// <summary>This variable holds the settings (whether to show line numbers, 
        /// etc.) that all editor controls share.</summary>
        ITextEditorProperties _editorSettings;



        /// <summary>
        /// Replaces the entire text of the xml view with the xml in the
        /// specified. The xml will be formatted.
        /// </summary>
        public void FormatXml(string xml)
        {
            string formattedXml = IndentedFormat(SimpleFormat(IndentedFormat(xml)));
            textBox.Document.Replace(0, textBox.Document.TextLength, formattedXml);
            UpdateFolding();
        }

        /// <summary>
        /// Forces the editor to update its folds.
        /// </summary>
        void UpdateFolding()
        {
            textBox.Document.FoldingManager.UpdateFoldings(String.Empty, null);
            textBox.ActiveTextAreaControl.TextArea.Refresh();
        }

        /// <summary>
        /// Returns a formatted xml string using a simple formatting algorithm.
        /// </summary>
        static string SimpleFormat(string xml)
        {
            return xml.Replace("><", ">\r\n<");
        }

        /// <summary>
        /// Returns a pretty print version of the given xml.
        /// </summary>
        /// <param name="xml">Xml string to pretty print.</param>
        /// <returns>A pretty print version of the specified xml.  If the
        /// string is not well formed xml the original string is returned.
        /// </returns>
        string IndentedFormat(string xml)
        {
            string indentedText = String.Empty;

            try
            {
                XmlTextReader reader = new XmlTextReader(new StringReader(xml));
                reader.WhitespaceHandling = WhitespaceHandling.None;

                StringWriter indentedXmlWriter = new StringWriter();
                XmlTextWriter writer = CreateXmlTextWriter(indentedXmlWriter);
                writer.WriteNode(reader, false);
                writer.Flush();

                indentedText = indentedXmlWriter.ToString();
            }
            catch (Exception)
            {
                indentedText = xml;
            }

            return indentedText;
        }

        XmlTextWriter CreateXmlTextWriter(TextWriter textWriter)
        {
            XmlTextWriter writer = new XmlTextWriter(textWriter);
            if (textBox.TextEditorProperties.ConvertTabsToSpaces)
            {
                writer.Indentation = textBox.TextEditorProperties.IndentationSize;
                writer.IndentChar = ' ';
            }
            else
            {
                writer.Indentation = 1;
                writer.IndentChar = '\t';
            }
            writer.Formatting = Formatting.Indented;
            return writer;
        }

        private void InitForm()
        {
            IDictionary syntaxModes = ConfigurationManager.GetSection("SyntaxModes") as IDictionary;
            if (syntaxModes != null)
            {
                foreach (string key in syntaxModes.Keys)
                {
                    ToolStripMenuItem miNewMode = new ToolStripMenuItem();
                    miNewMode.Name = "mi" + key;
                    //this.miNewMode.Size = new System.Drawing.Size(174, 22);
                    miNewMode.Text = key;
                    miNewMode.Tag = syntaxModes[key];
                    miNewMode.Click += new System.EventHandler(
                        delegate(object sender, EventArgs e)
                        {
                            ToolStripMenuItem miThis = sender as ToolStripMenuItem;
                            if (miThis != null && miThis.Tag != null)
                            {
                                ToolStripDropDownMenu owner = miThis.Owner as ToolStripDropDownMenu;
                                if (owner != null && owner.Items.Count > 0)
                                {
                                    foreach (ToolStripMenuItem mi in owner.Items)
                                    {
                                        mi.Checked = false;
                                    }
                                    miThis.Checked = true;
                                }
                                if (textBox != null)
                                {
                                    textBox.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy(miThis.Tag as string);
                                }
                            }
                        });
                    if (key == "XML")
                    {
                        miNewMode.Checked = true;
                        textBox.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("XML");
                    }
                    //this.miViewMode.DropDownItems.Add(miNewMode);
                }
            }

            if (_editorSettings == null)
            {
                _editorSettings = textBox.TextEditorProperties;
                OnSettingsChanged();
            }
            else
                textBox.TextEditorProperties = _editorSettings;

            if (!(textBox.Document.FoldingManager.FoldingStrategy is XmlFoldingStrategy))
            {
                textBox.Document.FoldingManager.FoldingStrategy = new XmlFoldingStrategy();
            }
            UpdateFolding();
        }


        /// <summary>Show current settings on the Options menu</summary>
        /// <remarks>We don't have to sync settings between the editors because 
        /// they all share the same DefaultTextEditorProperties object.</remarks>
        private void OnSettingsChanged()
        {
            if (_editorSettings == null)
            {
                _editorSettings = textBox.TextEditorProperties;
            }

            //textBox.IsSplited;
            _editorSettings.ShowSpaces = this.CM_showSpaceTab.Checked;
            _editorSettings.ShowEOLMarker = this.CM_showEOLMarker.Checked;
            _editorSettings.ShowInvalidLines = this.CM_showInvalidLine.Checked;
            //_editorSettings.LineViewerStyle = LineViewerStyle.FullRow;
            // _editorSettings.BracketMatchingStyle == BracketMatchingStyle.After;
            _editorSettings.AllowCaretBeyondEOL = !_editorSettings.AllowCaretBeyondEOL;
            _editorSettings.ShowLineNumbers = this.CM_showLineNumbers.Checked;

            textBox.ConvertTabsToSpaces = !textBox.ConvertTabsToSpaces;

            /*
            //this.CM_splitWindow.Checked = textBox.IsSplited;
            this.CM_showSpaceTab.Checked = _editorSettings.ShowSpaces;
            this.CM_showEOLMarker.Checked = _editorSettings.ShowEOLMarker;
            this.CM_showInvalidLine.Checked = _editorSettings.ShowInvalidLines;
            this.CM_showHighlightLine.Checked = _editorSettings.LineViewerStyle == LineViewerStyle.FullRow;
            //this.CM_showHLCurRow.Checked = _editorSettings.BracketMatchingStyle == BracketMatchingStyle.After;
            this.CM_showVirtualSapce.Checked = _editorSettings.AllowCaretBeyondEOL;
            this.CM_showLineNumbers.Checked = _editorSettings.ShowLineNumbers;

            this.CM_tabToSpace.Checked = textBox.ConvertTabsToSpaces;
            */
        }


        #endregion

        #region 常用编辑选项

        /// <summary>Performs an action encapsulated in IEditAction.</summary>
        /// <remarks>
        /// There is an implementation of IEditAction for every action that 
        /// the user can invoke using a shortcut key (arrow keys, Ctrl+X, etc.)
        /// The editor control doesn't provide a public funciton to perform one
        /// of these actions directly, so I wrote DoEditAction() based on the
        /// code in TextArea.ExecuteDialogKey(). You can call ExecuteDialogKey
        /// directly, but it is more fragile because it takes a Keys value (e.g.
        /// Keys.Left) instead of the action to perform.
        /// <para/>
        /// Clipboard commands could also be done by calling methods in
        /// editor.ActiveTextAreaControl.TextArea.ClipboardHandler.
        /// </remarks>
        private void DoEditAction(TextEditorControl editor, ICSharpCode.TextEditor.Actions.IEditAction action)
        {
            if (editor != null && action != null)
            {
                TextArea area = editor.ActiveTextAreaControl.TextArea;
                editor.BeginUpdate();
                try
                {
                    lock (editor.Document)
                    {
                        action.Execute(area);
                        if (area.SelectionManager.HasSomethingSelected && area.AutoClearSelection /*&& caretchanged*/)
                        {
                            if (area.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal)
                            {
                                area.SelectionManager.ClearSelection();
                            }
                        }
                    }
                }
                finally
                {
                    editor.EndUpdate();
                    area.Caret.UpdateCaretPosition();
                }
            }
        }


        /// <summary>
        /// 是否选中
        /// </summary>
        /// <returns></returns>
        private bool HaveSelection()
        {
            TextEditorControl editor = textBox;
            return editor != null &&
                editor.ActiveTextAreaControl.TextArea.SelectionManager.HasSomethingSelected;
        }

        /// <summary>
        /// 剪切
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditCut_Click(object sender, EventArgs e)
        {
            if (HaveSelection())
                DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.Cut());
        }

        /// <summary>
        /// 复制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditCopy_Click(object sender, EventArgs e)
        {
            if (HaveSelection())
                DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.Copy());
        }

        /// <summary>
        /// 粘贴
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditPaste_Click(object sender, EventArgs e)
        {
            DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.Paste());
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditDelete_Click(object sender, EventArgs e)
        {
            if (HaveSelection())
                DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.Delete());
        }

        /// <summary>
        /// 全选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditSelectAll_Click(object sender, EventArgs e)
        {
            DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.SelectWholeDocument());
        }

        //查找替换
        FindAndReplaceForm _findForm = new FindAndReplaceForm();

        /// <summary>
        /// 查找
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditFind_Click(object sender, EventArgs e)
        {
            TextEditorControl editor = textBox;
            if (editor == null) return;
            _findForm.ShowFor(editor, false);
        }

        /// <summary>
        /// 替换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditReplace_Click(object sender, EventArgs e)
        {
            TextEditorControl editor = textBox;
            if (editor == null) return;
            _findForm.ShowFor(editor, true);
        }

        /// <summary>
        /// 查找下一个
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditFindNext_Click(object sender, EventArgs e)
        {
            _findForm.FindNext(true, false,
                string.Format("没有找到你要查找的内容！", _findForm.LookFor));
        }

        /// <summary>
        /// 查找上一个
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEditFindPrev_Click(object sender, EventArgs e)
        {
            _findForm.FindNext(true, true,
                string.Format("没有找到你要查找的内容！", _findForm.LookFor));
        }

        /// <summary>
        /// 取消\设置书签
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miToggleBookmark_Click(object sender, EventArgs e)
        {
            TextEditorControl editor = textBox;
            if (editor != null)
            {
                DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.ToggleBookmark());
                editor.IsIconBarVisible = editor.Document.BookmarkManager.Marks.Count > 0;
            }
        }

        /// <summary>
        /// 转到下一书签
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miGoToNextBookmark_Click(object sender, EventArgs e)
        {
            DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.GotoNextBookmark(new Predicate<Bookmark>(delegate(Bookmark bookmark)
            {
                return true;
            })));
        }

        /// <summary>
        /// 转到前一书签
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miGoToPrevBookmark_Click(object sender, EventArgs e)
        {
            DoEditAction(textBox, new ICSharpCode.TextEditor.Actions.GotoPrevBookmark(new Predicate<Bookmark>(delegate(Bookmark bookmark)
            {
                return true;
            })));
        }

        /// <summary>
        /// 格式化xml文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miFormatXml_Click(object sender, EventArgs e)
        {
            try
            {
                FormatXml(textBox.Document.TextContent);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(String.Format("Xml格式化失败：{0}", ex.ToString()));
            }
        }

        #endregion



    }
}